﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Text.RegularExpressions;

namespace RibbonEditor.Controls
{
    class UserControlHelper
    {
        public static bool IsControlValid(UserControl container)
        {
            foreach (Control ctrl in container.Controls)
            {
                if (!(ctrl is UserControl))
                    continue;

                var usrControl = (UserControl) ctrl;

                switch (usrControl.GetType().Name)
                {
                    case "BooleanControl":
                        {
                            // Rien à valider
                            //BooleanControl c = ((BooleanControl))ctrl;
                        }
                        break;
                    case "DecimalControl":
                        {
                            DecimalControl c = (DecimalControl)usrControl;

                            if (c.IsRequired && !c.Value.HasValue)
                            {
                                return false;
                            }
                        }
                        break;
                    case "Integer":
                        {
                            IntegerControl c = (IntegerControl)usrControl;

                            if (c.IsRequired && !c.Value.HasValue)
                            {
                                return false;
                            }
                        }
                        break;
                    case "EnumControl":
                        {
                            EnumControl c = (EnumControl)usrControl;

                            if (c.IsRequired && c.SelectedValue == "<no value selected>")
                            {
                                return false;
                            }
                        }
                        break;
                    case "ReferencedControl":
                        {
                            ReferencedControl c = (ReferencedControl)usrControl;

                            if (c.IsRequired && string.IsNullOrEmpty(c.Value))
                            {
                                return false;
                            }
                        }
                        break;
                    case "StringControl":
                        {
                            StringControl c = (StringControl)usrControl;

                            if (c.IsRequired && string.IsNullOrEmpty(c.Value))
                            {
                                return false;
                            }

                            if (!string.IsNullOrEmpty(c.Format))
                            {
                                if (c.Format.ToLower() == "h")
                                {
                                    Regex re = new Regex("^#([a-fA-F0-9]{6})");
                                    if (!re.Match(c.Value).Success)
                                    {
                                        MessageBox.Show(c, "Input is not valid hexadecimal value", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                                    }
                                }
                            }
                        }
                        break;
                }
            }

            return true;
        }
    
        public static bool LeaveControl(UserControl control)
        {
            bool isDirty = false;

            foreach (object ctrl in control.Controls)
            {
                if (!(ctrl is IDirtable))
                    continue;

                isDirty = isDirty || ((IDirtable)ctrl).IsDirty;
            }

            if (isDirty)
            {
                if (DialogResult.Yes == MessageBox.Show(control, "You didn't save your changes! Do you want to save them now?", "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
                {
                    foreach (object ctrl in control.Controls)
                    {
                        if (!(ctrl is IDirtable))
                            continue;
                        
                        ((IDirtable)ctrl).IsDirty = false;
                    }

                    return true;
                }
                else
                {
                    foreach (object ctrl in control.Controls)
                    {
                        if (!(ctrl is IDirtable))
                            continue;

                        ((IDirtable)ctrl).ReinitValues();
                    }

                    foreach (object ctrl in control.Controls)
                    {
                        if (!(ctrl is IDirtable))
                            continue;

                        ((IDirtable)ctrl).IsDirty = false;
                    }
                }
            }

            return false;
        }

        public static void CleanDirtyFields(UserControl control)
        {
            foreach (object ctrl in control.Controls)
            {
                if (!(ctrl is IDirtable))
                    continue;

                ((IDirtable)ctrl).IsDirty = false;
            }
        }

        public static UserControl GetRuleUserControl(string ruleName, object rule)
        {
            UserControl ctrl = null;

            Assembly assembly = Assembly.GetExecutingAssembly();
            AssemblyName assemblyName = assembly.GetName();

            Type t = Type.GetType(assemblyName.Name + ".Controls.Rules." + ruleName + "Control");
            ctrl = (UserControl)Activator.CreateInstance(t, new object[] { rule });

            return ctrl;
        }

        public static UserControl GetCommandUIDefinitionUserControl(string cuidName, object cuidObject)
        {
            UserControl ctrl = null;

            Assembly assembly = Assembly.GetExecutingAssembly();
            AssemblyName assemblyName = assembly.GetName();

            Type t = Type.GetType(assemblyName.Name + ".Controls.CommandUIDefinitions." + cuidName + "Control");

            if (t != null)
            {
                ctrl = (UserControl)Activator.CreateInstance(t, new object[] { cuidObject });
                return ctrl;
            }
            else
            {
                return null;
            }
        }


        internal static UserControl GetActionUserControl(string actionName, object actionObject)
        {
            UserControl ctrl = null;

            Assembly assembly = Assembly.GetExecutingAssembly();
            AssemblyName assemblyName = assembly.GetName();

            Type t = Type.GetType(assemblyName.Name + ".Controls.Actions." + actionName + "Control");

            if (t != null)
            {
                ctrl = (UserControl)Activator.CreateInstance(t, new object[] { actionObject });
                return ctrl;
            }
            else
            {
                return null;
            }
        }

        internal static UserControl GetParameterUserControl(string parameterName, object parameterObject)
        {
            UserControl ctrl = null;

            Assembly assembly = Assembly.GetExecutingAssembly();
            AssemblyName assemblyName = assembly.GetName();

            Type t = Type.GetType(assemblyName.Name + ".Controls.Actions.Parameters." + parameterName + "Control");

            if (t != null)
            {
                ctrl = (UserControl)Activator.CreateInstance(t, new object[] { parameterObject });
                return ctrl;
            }
            else
            {
                return null;
            }
        }

        internal static UserControl GetTemplateUserControl(string templateName, object templateObject)
        {
            UserControl ctrl = null;

            Assembly assembly = Assembly.GetExecutingAssembly();
            AssemblyName assemblyName = assembly.GetName();

            Type t = Type.GetType(assemblyName.Name + ".Controls.Templates." + templateName + "Control");

            if (t != null)
            {
                ctrl = (UserControl)Activator.CreateInstance(t, new object[] { templateObject });
                return ctrl;
            }
            else
            {
                return null;
            }
        }
    }

}
